import pymysql
import re


class ConDb():
    def openClose(fun):
        def run(self, sql=None):
            # 创建数据库连接
            db = pymysql.connect(host="localhost", port=3306, user="root", password="root", db="zsh", charset="utf8")
            # 创建游标
            cursor = db.cursor()
            try:
                # 使用装饰器，fun是装饰器的参数。。。运行sql语句
                cursor.execute(fun(self, sql))
                # 得到返回值
                li = cursor.fetchall()
                # 提交事务
                db.commit()
            except Exception as e:
                # 如果出现错误，回滚事务
                db.rollback()
                # 打印报错信息
                print('运行', str(fun), '方法时出现错误，错误代码：', e)
            finally:
                # 关闭游标和数据库连接
                cursor.close()
                db.close()
            try:
                # 返回sql执行信息
                return list(li)

            except:
                print('没有得到返回值，请检查代码，该信息出现在ConDb类中的装饰器方法')

        return run

    # runSql 未经封装，可直接运行sql
    @openClose
    def runSql(self, sql):  # 调用该方法执行sql
        print('调试专用，显示sql：', sql)
        return sql

    # 切换数据库
    def tab(self, db):
        sql = 'use {}'.format(db)
        self.runSql(sql)

    # 创建数据库
    def create_DB(self, name):
        sql = '''CREATE  DATABASE {} '''.format(name)
        self.runSql(sql)

    # 创建表
    def create_TB(self, dbname='', tbname='', enging="InnoDB", charset="utf8", **kwargs):
        '''
        :param dbname:  数据库名称
        :param tbname:  表名称
        :param enging:  数据引擎
        :param charset: 默认编码
        :param kwargs: 新建的列 和 索引
        :return:
        PRIMARY="KEY('id')"  设置主键索引 id 替换成要设置成主键的列
        UNIQUE = "KEY `name` (`name`)"  设置上下文索引，name 可替换
        '''
        '''
        使用案例：

        import conMySql
        con=conMySql.ConDb()
        con.create_TB('test','student1',id="int(10)",name="varchar(255)",PRIMARY="KEY('id')" ,UNIQUE = "KEY `name` (`name`)" )

        '''

        self.runSql('''use {}'''.format(dbname))
        li = []
        for k, v in kwargs.items():
            li.append('{} {}'.format(k, v))
        sql = '''
            CREATE TABLE `{}` (
                "{}"
            ) ENGINE={}  DEFAULT CHARSET={}

            '''.format(tbname, li, enging, charset)
        sql = re.sub(r"""\'|\"|\[|\]""", '', sql)
        self.runSql(sql)

    # 插入数据
    def insert_TB(self, tableName, items, *args):
        '''
        :param tableName:  插入的表名
        :param items: 数据源，是一个不嵌套的list
        :param args:  指定列，不填写不指定
        :return:
        '''
        '''
        使用案例：

        import conMySql
        con=conMySql.ConDb()

        不指定插入列
        con.insert_TB('tableName',数据源 )


        插入指定列
        con.insert_TB('tableName',数据源,'列名1','列名2')

        '''
        args = str(args)
        args = re.sub("'", '', args)

        items = re.sub(r"\[|\]", '', str(items))
        if items:
            sql = '''
            INSERT  INTO {} {} VALUES ({})
            '''.format(tableName, args, items)
        else:
            sql = '''
            INSERT  INTO {}  VALUES ({})
            '''.format(tableName, items)
        self.runSql(sql)

